package org.joot.jmir2.display;

import static org.lwjgl.opengl.GL11.*;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.nio.ByteBuffer;

import org.apache.log4j.Logger;
import org.joot.jmir2.exception.JMir2Exception;
import org.joot.jmir2.util.AllCache;
import org.joot.jmir2.util.Misc;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GLContext;

public final class Application {
	/** log */
	private static Logger log = Logger.getLogger(Application.class);
	/** 图形信息 */
	private Graphics graphics = Graphics.get();
	/** 游戏 */
	private ApplicationListener listener;
	/** 游戏进行时 */
	private boolean running = true;
	/** 缓存 */
	private AllCache cache = AllCache.get();
	
	/* 单例 */
	private Application() { }
	private static Application single = new Application();
	public static Application get() {
		return single;
	}
	
	
	/**
	 * 初始化
	 */
	public void initialize(ApplicationConfig config, ApplicationListener listener) {
		if(config.fullscreen) {
			config.resizable = false;
			Dimension screenSize= Toolkit.getDefaultToolkit().getScreenSize();
			graphics.width = screenSize.width;
			graphics.height = screenSize.height;
		} else {
			graphics.width = config.width;
			graphics.height = config.height;
		}
		graphics.maxFps = config.fps;
		setupDisplay(config.fullscreen, config.resizable);
		setupOpenGL();
		graphics.isNonpoweroftwoSupport = GLContext.getCapabilities().GL_ARB_texture_non_power_of_two;
		this.listener = listener;
	}
	
	/**
	 * 开始图形绘制主循环
	 */
	public void mainLoop() {
		if(this.listener == null) {
			JMir2Exception exception = JMir2Exception.valueOf(null, JMir2Exception.EXCEPTION_TYPE_CALC);
			log.error(exception.getMessage(), exception);
			throw exception;
		}
		listener.create();
		graphics.lastTime = System.nanoTime();
		while(this.running) {
			//清屏
			glClear(GL_COLOR_BUFFER_BIT);
			
			// 是否退出
			Display.processMessages();
			this.running = !Display.isCloseRequested() && !listener.isRequestExit();
			if(!this.running) break;
			
			// 加载资源
			cache.updateLoaders();
			// 更新时间
			graphics.updateTime();
			// 渲染
			listener.render();
			
			Display.update();
			Display.sync(graphics.maxFps);
		}
		
		// 循环结束
		listener.dispose();
		Display.destroy();
	}
	
	/**
	 * 设置显示
	 * 
	 * @param fullscreen
	 * 			是否全屏显示
	 * @param resizable
	 * 			是否支持用户缩放窗体
	 */
	private void setupDisplay(boolean fullscreen, boolean resizable) {
		try {
			// 创建显示
			// 窗体宽高
			Display.setDisplayMode(new DisplayMode(graphics.width, graphics.height));
			// 是否全屏展示
			Display.setFullscreen(fullscreen);
			// 是否可缩放窗体
			Display.setResizable(resizable);
			// 标题
			Display.setTitle("JMir2");
			// 等待垂直同步
			Display.setVSyncEnabled(true);
			// 图标
			Display.setIcon(new ByteBuffer[]{
					Misc.imageToIcon("/resources/Icon32.png"),
					Misc.imageToIcon("/resources/Icon16.png")// TODO mac的128
			});

			Display.create();
		} catch (LWJGLException e) {
			JMir2Exception exception = JMir2Exception.valueOf(e, JMir2Exception.EXCEPTION_TYPE_ENV);
			log.error(exception.getMessage(), exception);
			throw exception;
		}
	}
	
	/**
	 * 设置OpenGL参数
	 */
	private void setupOpenGL() {
		// 操作投影矩阵
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity(); // 复位
		// 将坐标系置为左上角(0,0)，右下角(width,height)
		glOrtho(0, graphics.width, graphics.height, 0, 1, -1);
		// 操作模型矩阵
		glMatrixMode(GL_MODELVIEW);
		// 开启2D纹理支持
		glEnable(GL_TEXTURE_2D);
		// 开启混合渲染
		glEnable(GL_BLEND);
	}
}